home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Plus / Multimedia Plus with ClearVue Version 10-94 (Knowledge Media Inc.).ISO / dos / anim / artform / playback.c < prev    next >
C/C++ Source or Header  |  1992-10-03  |  15KB  |  642 lines

  1. /********************************************************/
  2. /*                                */
  3. /*    Main function and general user interfaces    */
  4. /*                            */
  5. /********************************************************/
  6. /* include files */
  7.  
  8. #include <io.h>
  9. #include <dos.h>
  10. #include <conio.h>
  11. #include <ctype.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <malloc.h>
  16.  
  17. /********************************************************/
  18. /* Prototypes */
  19.  
  20. void    videoplayback (char *, int, int);
  21. long    videoload (char *, long);
  22. long    contload (char *, long);
  23. void    *loadlist (char *, int);
  24.  
  25. void    _far _interrupt playback ();
  26. void    (_far _interrupt *oldfun) (void);
  27. void    fastplay (void);
  28.  
  29. void    videomode (void *);
  30. int    loadchart (void *, char *);
  31. void    videorecall (void *);
  32. void    loadcount (unsigned);
  33. char    videotest (void);
  34. void    textmode (void);
  35.  
  36. void    romprint (char *);
  37.  
  38. /********************************************************/
  39. /* Constants and macros */
  40.  
  41. #define MAXVID 200
  42. #define FILEMAX 100
  43.  
  44. #define MK_FP(seg,ofs)    ((void far *) \
  45.             (((unsigned long)(seg) << 16) | (unsigned)(ofs)))
  46.  
  47. #define pokeb(a,b,c)    (*((char far*)MK_FP((a),(b))) = (char)(c))
  48.  
  49. /********************************************************/
  50. /* Data structures */
  51.  
  52. typedef    struct {
  53.     int    xpos;        /* top, left corner of display window */
  54.     int    ypos;
  55.     int    xlen;        /* size of window */
  56.     int    ylen;
  57.     unsigned base;        /* window top, left corner displacement */
  58.     unsigned size;        /* total number of bytes in frame */
  59.     void    *data;        /* pointer to frame data */
  60.         } frame;
  61.  
  62. typedef    struct {
  63.     char    name[16];    /* video file name */
  64.     int    maxum;        /* number of frames */
  65.     long    size;        /* size in bytes */
  66.     frame    *photo[MAXVID]; /* pointers to frames */
  67.             } video;
  68.  
  69. typedef struct {        /* list file information */
  70.     int max;
  71.     char name[FILEMAX][10];
  72.     int rate[FILEMAX];
  73.         int cycle[FILEMAX];
  74.         } agenda;
  75.  
  76. /********************************************************/
  77. /* Main program procedure */
  78.  
  79. void    main (int argc, char *argv[]){
  80.  
  81. int    vest;
  82. int    rate;
  83. int    cycle;
  84. int    index;
  85. int    order;
  86. unsigned count;
  87. agenda    *list;
  88.  
  89.     rate = 0;
  90.     cycle = 0;
  91.  
  92.     romprint ("");
  93.     romprint ("-=≡ARTFORM 3D≡=- Animated Graphics Playback");
  94.  
  95.     vest = videotest ();
  96.     if (vest != 8){
  97.         romprint ("> VGA color video adapter required. Continue ? (Y/N)");
  98.         order = getch ();
  99.         if (order == 'Y' || order == 'y');
  100.         else return;}
  101.  
  102.     romprint ("> Loading video file");
  103.     romprint ("> Please wait ...");
  104.  
  105.     if (argc <= 1 || argc >= 5){
  106.         romprint ("> Playback <filename>  {rate}  {count}");
  107.                 romprint (">          video/list optional optional");
  108.         return;}
  109.  
  110.     if (argc == 3 || argc == 4) rate = atoi (argv[2]);
  111.  
  112.     if (argc == 4) cycle = atoi (argv[3]);
  113.  
  114.     list = loadlist (argv[1],rate);
  115.  
  116.     if (list == NULL) videoplayback (argv[1], cycle, rate);
  117.  
  118.     else {  do {    index = 0;
  119.             while (index < list->max && kbhit () == 0){
  120.                 videoplayback (list->name[index],list->cycle[index],list->rate[index]);
  121.                 index++;}
  122.                     if (cycle >= 0) cycle--;
  123.             if (cycle == 0) ungetch (27);}
  124.         while (kbhit () == 0);
  125.         free (list);}
  126.  
  127.     loadcount (0);
  128.         textmode ();
  129.         return;}
  130.  
  131. /********************************************************/
  132. /* Test for VGA */
  133.  
  134. char    videotest (){
  135.  
  136. char    vest;
  137.  
  138.     _asm {    mov ax,1A00h
  139.         int 10h
  140.         mov vest,bl}
  141.  
  142.     return (vest);}
  143.  
  144. /*********************************************************/
  145. /* Mode 0x13 VGA 320 x 200 and 256 color */
  146.  
  147. void    videomode (void *pointer){
  148.  
  149.     _asm {    mov ax,1200h    /* enable palette init */
  150.         mov bl,31h
  151.         int 10h
  152.  
  153.         mov ax,13h    /* video mode */
  154.         int 10h
  155.  
  156.         mov ax,1012h    /* load new palette */
  157.         mov bx,0
  158.         mov cx,256
  159.         les dx,pointer
  160.         int 10h }
  161.  
  162.     return;}
  163.  
  164. /********************************************************/
  165. /* Standard text mode */
  166.  
  167. void    textmode (){
  168.  
  169.     _asm {  mov ah,0    /* text mode */
  170.         mov al,3h
  171.         int 10h }}
  172.  
  173. /********************************************************/
  174. /* load the video file color chart */
  175.  
  176. int    loadchart (void *chart, char *filename){
  177.  
  178. FILE    *load;
  179. int    version[8];
  180.  
  181.         load = fopen (filename,"rb");
  182.  
  183.     if (load == NULL) return (0);
  184.  
  185.     else {    fread (&version,8,2,load);
  186.                 fread (chart,768,1,load);
  187.             fclose (load);}
  188.  
  189.     return (version[0]);}
  190.  
  191. /********************************************************/
  192. /* Print message in DOS */
  193.  
  194. void    romprint (char *message){
  195.  
  196. int    n = 0;
  197. char    chr;
  198.  
  199.     while (message[n] != 0){
  200.  
  201.         chr = message[n];
  202.  
  203.             _asm {    mov ah,0Eh
  204.             mov al,chr
  205.             mov bh,0
  206.             int 10h}
  207.         n++;}
  208.  
  209.         _asm {    mov ah,0Eh
  210.         mov al,10
  211.         mov bh,0
  212.         int 10h}
  213.  
  214.         _asm {    mov ah,0Eh
  215.         mov al,13
  216.         mov bh,0
  217.         int 10h}
  218.  
  219.     return;}
  220.  
  221. /********************************************************/
  222. /* Set timer/counter for frame rate interrupt */
  223.  
  224. void    loadcount (unsigned word){
  225.  
  226. int msb,lsb;
  227.  
  228.     lsb = word & 255;
  229.     msb = (word >> 8) & 255;
  230.  
  231.     outp (0x43,54);
  232.     outp (0x40,lsb);
  233.     outp (0x40,msb);
  234.  
  235.     return;}
  236.  
  237. /********************************************************/
  238. /* Global variables */
  239.  
  240. int    cell;
  241. int    frax;
  242. int    division;
  243. int    cont;
  244. int    link;
  245. video    *film;
  246.  
  247. /********************************************************/
  248. /* Test and read list file */
  249.  
  250. void    *loadlist (char *tempfile, int rate){
  251.  
  252. FILE    *load;
  253. int    t,len,flag;
  254. char    buffer[16];
  255. char    listfile[16];
  256. char    line[128];
  257. agenda    *list;
  258.  
  259.     strcpy (listfile,tempfile);
  260.     if (strstr (listfile,".lst") == NULL) strcat (listfile,".lst");
  261.     if (access (listfile,0) != 0) return (NULL);
  262.  
  263.     list = malloc (sizeof (agenda));
  264.     list->max = 0;
  265.     for (len = 0; len < FILEMAX; len++) list->name[len][0] = 0;
  266.  
  267.     load = fopen (listfile,"rt");
  268.     while (ferror (load) == 0 && feof (load) == 0 && list->max < FILEMAX){
  269.  
  270.         if (fgets (line,128,load) == NULL) break;
  271.  
  272.         t = 0;
  273.                 len = 0;
  274.                 while (isalnum (line[t]) != 0){
  275.             list->name[list->max][len] = line[t];
  276.                         len++;
  277.             t++;}
  278.                 list->name[list->max][len] = 0;
  279.  
  280.         if (line[t] == 32){
  281.             len = 0;
  282.             t++;
  283.                     while (isdigit (line[t]) != 0 && len < 16){
  284.                 buffer[len] = line[t];
  285.                             len++;
  286.                 t++;}
  287.                     buffer[len] = 0;
  288.             list->rate[list->max] = atoi (buffer);}
  289.         else list->rate[list->max] = rate;
  290.  
  291.         if (line[t] == 32){
  292.             len = 0;
  293.             t++;
  294.                     while (isdigit (line[t]) != 0 && len < 16){
  295.                 buffer[len] = line[t];
  296.                             len++;
  297.                 t++;}
  298.                     buffer[len] = 0;
  299.             list->cycle[list->max] = atoi (buffer);}
  300.         else list->cycle[list->max] = 1;
  301.  
  302.         list->max++;}
  303.  
  304.     fclose (load);
  305.     return (list);}
  306.  
  307. /********************************************************/
  308. /* Play back video file */
  309.  
  310. void    videoplayback (char *filename, int cycle, int rate){
  311.  
  312. int    n,order,len,base;
  313. int    count,pos;
  314. long    offset;
  315. unsigned init;
  316. char    buffer[16];
  317. char    *vgamem = MK_FP (0xA000,0);
  318. void    *palette;
  319.  
  320.     division = 2;
  321.         if (rate > 0){
  322.         if (rate < 10) division = 20 / rate + 1;
  323.         init = (unsigned) (1.19e6 / division / rate);}
  324.  
  325.     palette = malloc (768);
  326.         film = malloc (sizeof (video));
  327.  
  328.     strcpy (buffer,filename);
  329.     if (strstr (buffer,".vdo") == NULL) strcat (buffer,".vdo");
  330.  
  331.     order = loadchart (palette,buffer);
  332.     if (order != 2) goto escape;
  333.  
  334.         offset = videoload (buffer,0);
  335.         if (offset == 0) cont = 0;
  336.     else cont = 1;
  337.  
  338.     videomode (palette);
  339.  
  340.         cell = 0;
  341.         order = 25;
  342.         if (cycle == 0) cycle--;
  343.         while (cycle != 0 && film->maxum > 0 && order == 25){
  344.  
  345.         if (rate == 0){
  346.             fastplay ();
  347.  
  348.             order = getch ();
  349.             if (order == 0) order = getch ();
  350.                     while (kbhit () != 0) getch ();
  351.             if (order == 27) ungetch (27);
  352.  
  353.             if (cont == 1) for (n=0;n<film->maxum;n++){
  354.                 free (film->photo[n]->data);
  355.                 free (film->photo[n]);}
  356.  
  357.                         if (order == 25 && offset == 0 && cycle > 0) cycle--;
  358.  
  359.             if (order != 25 || cont == 1 || cycle == 0){
  360.                 for (n=0;n<film->maxum;n++){
  361.                     free (film->photo[n]->data);
  362.                     free (film->photo[n]);}}
  363.  
  364.                         if (order == 25 && cont == 1 && cycle != 0)
  365.                                 offset = videoload (buffer,offset);}
  366.  
  367.         else {    _disable ();
  368.             loadcount (init);
  369.             frax = division;
  370.                            oldfun = _dos_getvect (0x1C);
  371.             _dos_setvect (0x1C,playback);
  372.             link = cycle;
  373.             _enable ();
  374.  
  375.             if (cont == 1 && offset != 0)
  376.                 offset = contload (buffer,offset);
  377.                         else while (kbhit () == 0);
  378.  
  379.             _disable ();
  380.             cycle = link;
  381.                            _dos_setvect (0x1C,oldfun);
  382.             _enable ();
  383.             loadcount (0);
  384.  
  385.             order = getch ();
  386.             if (order == 0) order = getch ();
  387.                     while (kbhit () != 0) getch ();
  388.             if (order == 27) ungetch (27);
  389.  
  390.             if (offset == 0 && cycle > 0) cycle--;
  391.  
  392.             if (order != 25 || cycle == 0){
  393.                 for (n=0;n<film->maxum;n++){
  394.                     free (film->photo[n]->data);
  395.                     free (film->photo[n]);}}
  396.  
  397.             if (order != 25) break;
  398.  
  399.                         if (cont == 1 && order == 25 && cycle != 0)
  400.                 offset = videoload (buffer,offset);}}
  401.  
  402. escape:    free (film);
  403.     free (palette);}
  404.  
  405. /********************************************************/
  406. /* Load a video file */
  407.  
  408. long    videoload (char *filename, long offset){
  409.  
  410. FILE    *load;
  411. int    num;
  412. int    flag;
  413. int    xpos;
  414. int    ypos;
  415. int    xlen;
  416. int    ylen;
  417. long    base;
  418. long    size;
  419. void    *data;
  420.  
  421.     film->size = 0;
  422.         film->maxum = 0;
  423.         load = fopen (filename,"rb");
  424.     num = fileno (load);
  425.  
  426.     lseek (num,784,0);
  427.     if (offset > 0) lseek (num,offset,1);
  428.  
  429.     do {    flag = 0;
  430.         if (film->maxum == MAXVID) flag = 2;
  431.  
  432.         else if (eof (num) == 0){
  433.             film->photo[film->maxum] = malloc (sizeof (frame));
  434.                         if (film->photo[film->maxum] == NULL) flag = 2;
  435.                         else {  read (num,&xpos,2);
  436.                                 read (num,&ypos,2);
  437.                                 read (num,&xlen,2);
  438.                                 read (num,&ylen,2);
  439.                                 read (num,&base,4);
  440.                                 read (num,&size,4);
  441.                 if (size > 0){
  442.                     data = malloc ((unsigned) size);
  443.                     if (data == NULL){
  444.                         flag = 2;
  445.                         free (film->photo[film->maxum]);}
  446.                     else {    read (num, data, (unsigned) size);
  447.                         offset = offset + size + 16;
  448.                                         film->photo[film->maxum]->xpos = xpos;
  449.                                         film->photo[film->maxum]->ypos = ypos;
  450.                                         film->photo[film->maxum]->xlen = xlen;
  451.                                         film->photo[film->maxum]->ylen = ylen;
  452.                                         film->photo[film->maxum]->base = (unsigned) base;
  453.                                         film->photo[film->maxum]->size = (unsigned) size;
  454.                                         film->photo[film->maxum]->data = data;
  455.                         film->size = film->size + size;
  456.                         film->maxum++;}}}}
  457.         else flag = 1;}
  458.  
  459.     while (flag == 0);
  460.         fclose (load);
  461.  
  462.     if (flag == 2) return (offset);
  463.     return (0);}
  464.  
  465. /********************************************************/
  466. /* Continuously load a video file */
  467.  
  468. long    contload (char *filename, long offset){
  469.  
  470. FILE    *load;
  471. int    num;
  472. int    flag;
  473. int    xpos;
  474. int    ypos;
  475. int    xlen;
  476. int    ylen;
  477. long    base;
  478. long    size;
  479. void    *data;
  480.  
  481.         load = fopen (filename,"rb");
  482.     num = fileno (load);
  483.  
  484.     lseek (num,784,0);
  485.     if (offset > 0) lseek (num,offset,1);
  486.  
  487.     do {    while (film->maxum == MAXVID);
  488.  
  489.         if (eof (num) == 0){
  490.             do film->photo[film->maxum] = malloc (sizeof (frame));
  491.                         while (film->photo[film->maxum] == NULL);
  492.                         read (num,&xpos,2);
  493.                         read (num,&ypos,2);
  494.                         read (num,&xlen,2);
  495.                         read (num,&ylen,2);
  496.                         read (num,&base,4);
  497.                         read (num,&size,4);
  498.  
  499.             if (size > 0 && eof (num) == 0){
  500.                 do data = malloc ((unsigned) size);
  501.                 while (data == NULL);
  502.                                 read (num, data, (unsigned) size);
  503.                 offset = offset + size + 16;
  504.                                    film->photo[film->maxum]->xpos = xpos;
  505.                                    film->photo[film->maxum]->ypos = ypos;
  506.                                    film->photo[film->maxum]->xlen = xlen;
  507.                                    film->photo[film->maxum]->ylen = ylen;
  508.                                    film->photo[film->maxum]->base = (unsigned) base;
  509.                                    film->photo[film->maxum]->size = (unsigned) size;
  510.                                    film->photo[film->maxum]->data = data;
  511.                 film->size = film->size + size;
  512.                 film->maxum++;}}
  513.  
  514.         else {    while (kbhit () == 0);
  515.                     fclose (load);
  516.             return (0);}}
  517.  
  518.         while (kbhit () == 0);
  519.         fclose (load);
  520.         return (offset);}
  521.  
  522. /********************************************************/
  523. /* Prepare to display a video frame */
  524.  
  525. void _cdecl _far _interrupt playback (){
  526.  
  527. int    n;
  528.  
  529.         _disable ();
  530.  
  531.     frax--;
  532.     if (frax == 0){
  533.                 if (cont == 1){
  534.             if (film->maxum > 0){
  535.                 videorecall (film->photo[0]);
  536.                                 free (film->photo[0]->data);
  537.                             free (film->photo[0]);
  538.                 memcpy (&film->photo[0], &film->photo[1], film->maxum << 2);
  539.                 film->maxum--;}
  540.             else ungetch (25);}
  541.  
  542.         else {    videorecall (film->photo[cell]);
  543.                     cell++;
  544.                         if (cell == film->maxum){
  545.                 cell = 0;
  546.                                 if (link > 0) link--;
  547.                 if (link == 0) ungetch (25);}}
  548.  
  549.         frax = division;}
  550.  
  551.     else if (frax == 1) oldfun ();
  552.  
  553.     _enable ();}
  554.  
  555. /********************************************************/
  556. /* Display video frames continuously */
  557.  
  558. void    fastplay (){
  559.  
  560.     do {    _disable ();
  561.         videorecall (film->photo[cell]);
  562.         _enable ();
  563.  
  564.         cell++;
  565.                 if (cell == film->maxum){
  566.                         cell = 0;
  567.             ungetch (25);}}
  568.     while (kbhit () == 0);
  569.  
  570.     return;}
  571.  
  572. /********************************************************/
  573. /* Decompress and display a video frame */
  574.  
  575. void    videorecall (void *link){
  576.  
  577. frame    *photo = link;
  578. void    *data = photo->data;
  579. unsigned index = photo->ylen;
  580. unsigned base = photo->base;
  581.  
  582.     if (photo->size == 0) return;
  583.  
  584. _asm {          cld
  585.         push ds
  586.         push si
  587.         push di
  588.                 lds si,data
  589.         mov dx,base
  590.  
  591.     rego:    mov bx,[si]
  592.         cmp bx,0
  593.         jz  end
  594.         inc si
  595.         inc si
  596.                 mov cx,0A000h
  597.         mov es,cx
  598.         mov di,dx
  599.         mov cx,0
  600.  
  601.     mark:   lodsw
  602.                 mov cl,ah
  603.  
  604.                 cmp cl,0
  605.                 jz  single
  606.         cmp cl,255
  607.         jz  blank
  608.         jmp skip
  609.  
  610.         single: mov cl,al
  611.         sub bx,cx
  612.         rep movsb
  613.         dec bx
  614.         dec bx
  615.         jnz mark
  616.                 jmp end
  617.  
  618.     blank:    mov cl,al
  619.         add di,cx
  620.                 dec bx
  621.         dec bx
  622.         jnz mark
  623.         jmp end
  624.  
  625.     skip:    rep stosb
  626.         dec bx
  627.         dec bx
  628.         jnz mark
  629.  
  630.     end:    add dx,320
  631.         dec index
  632.         jnz rego
  633.                 pop di
  634.         pop si
  635.         pop ds}
  636.  
  637.     return;}
  638.  
  639. /********************************************************/
  640. /************************************************/
  641. /****************************************/
  642.